package com.kitmobile.data;

import java.util.HashMap;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;

import com.kitmobile.model.KITContact;

public class KITDatabase {

	private static final String DB_NAME = "kitmobile.db";
	private static final int DB_VERSION = 1;
	

	private KITDatabaseHelper dbOpener;
	private SQLiteDatabase db;
	
	public KITDatabase(Context context) {
		dbOpener = new KITDatabaseHelper(context);
	}
	
	public void open() {
		try {
			db = dbOpener.getWritableDatabase();
		}
		catch (SQLiteException exc) {
			db = dbOpener.getReadableDatabase();
		}
	}
	
	public void close() {
		db.close();
	}
	public Cursor query(SQLiteQueryBuilder queryBuilder, String selection) {
		return queryBuilder.query(db, null, selection, null, null, null, null);
	}
	
	public Cursor query(SQLiteQueryBuilder queryBuilder) {
		return queryBuilder.query(db, null, null, null, null, null, null);
	}
	
	public boolean insert(KITObject kitObj) {
		boolean returnVal = false; 
		
		if (kitObj.getId() == KITObject.ID_UNSET) {
			ContentValues values = new ContentValues();
			kitObj.toContentValues(values);
			long id = db.insert(kitObj.getTableName(), kitObj.getNullableColumn(), values);

			if (id != KITObject.ID_UNSET) { 
				kitObj.setId(id);
				kitObj.dirty = false;
				returnVal = true;
			}
		}
		return returnVal;
	}

	public boolean update(KITObject kitObj) {
		boolean returnVal = false;
		
		if (kitObj.isDirty()) {
			ContentValues values = new ContentValues();			
			kitObj.toContentValues(values);
			
			if (db.update(kitObj.getTableName(), values, TableData._ID + "=" + kitObj.getId(), null) > 0) {
				kitObj.dirty = false;
				returnVal = true;
			}
		}
		return returnVal;
	}
	
	public boolean delete(KITObject kitObj) {
		boolean returnVal = false;
		
		if (db.delete(kitObj.getTableName(), TableData._ID + "=" + kitObj.getId(), null) > 0) {
			kitObj.invalidate();
			returnVal = true;
		}
		return returnVal;
	}

	
	private static class KITDatabaseHelper extends SQLiteOpenHelper {

		public KITDatabaseHelper(Context context) {
			super(context, DB_NAME, null, DB_VERSION);
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			db.execSQL(KITContact.TableData.CREATE_TABLE_STATEMENT);
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + KITContact.TableData.TABLE_NAME);
            onCreate(db);
		}
	}
	
	public static interface TableData {
		public static final String _ID = "_id";
		public static final int _ID_COL = 0;
	}
	
	public static abstract class KITObject {
		
		public static final int ID_UNSET = Integer.MIN_VALUE;

		protected long id;
		protected boolean dirty;
		
		public KITObject() {
			invalidate();
		}

		public void invalidate() {
			id = ID_UNSET;
			dirty = true;
		}
		
		public boolean isDirty() {
			return dirty;
		}
		
		public long getId() {
			return id;
		}
		
		private final void setId(long id) {
			this.id = id;
		}
		
		public abstract void toContentValues(ContentValues values);
		
		public void fromCursor(Cursor cursor) {
			id = cursor.getLong(TableData._ID_COL);
		}
		
		public abstract String getTableName();	
		
		public abstract String getNullableColumn();

		public abstract HashMap<String, String> getProjectionMap();		

	}
}
